home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac-Source 1994 July
/
Mac-Source_July_1994.iso
/
C and C++
/
Entertainment
/
tblt
/
tblt⁄move.c
< prev
next >
Wrap
Text File
|
1986-09-06
|
7KB
|
224 lines
/*
* move.c - support for Tablut game moves.
*/
#include <quickdraw.h>
#include <window.h>
#include <memory.h>
#include "tablut.h"
/*
* movepiece() - attempt to move the given piece to the given grid location.
* Check the legality of the move;
* if the move is illegal, put the piece back where it was...
* otherwise, move the piece, record the move, and do any captures.
* NOTE: in setup mode almost all moves are legal,
* no moves are recorded, and no captures are made.
*/
movepiece(pidx, togridp)
int pidx; /* index of the piece to try to move */
Point *togridp; /* grid coords to try to move to */
{
struct pieceimage *p;
p = &piece[pidx];
if (!islegal(pidx, togridp)) { /* illegal move -- put it back */
if (!onboard(p)) removepiece(pidx);
else placepiece(pidx, p->grid.h, p->grid.v);
} else {
if (togridp->h == NOGRID) removepiece(pidx);
else placepiece(pidx, togridp->h, togridp->v);
if (!insetup) {
seecaptures(pidx); seeraichi(); writeboard();
}
}
}
/*
* islegal() - given a piece and a place to move it, islegal returns 1
* if that move is legal; 0 otherwise.
* NOTE: this routine assumes that findpiece() and dragpiece() have
* weeded out a large set of possible illegal moves. Islegal() only
* has to weed out the moves that they can't.
*/
int
islegal(pidx, togridp)
int pidx; /* index of the piece to try to move */
Point *togridp; /* grid coords to try to move to */
{
struct pieceimage *p;
p = &piece[pidx];
if (togridp->h == NOGRID) {
return(insetup); /* moving off-board is legal only in setup */
}
if (EqualPt(pass(p->grid), pass(*togridp))) {
return(0); /* already there -- that's no move */
}
if (togridp->h == 0 && togridp->v == 0 && p != &piece[THEKING]) {
return(0); /* only the king can occupy the throne */
}
if ((*gridp)[togridp->h][togridp->v]) {
return(0); /* can't move to an occupied square */
}
return(1);
}
/*
* seecaptures() - examine the board for captures that were caused by
* moving the given piece.
*/
seecaptures(pidx)
int pidx; /* index of the moved piece */
{
struct pieceimage *p; /* pointer to the moved piece */
short kh, kv; /* grid coords of the king */
short h, v;
p = &piece[pidx];
h = p->grid.h; v = p->grid.v;
trycapture((*gridp)[h-2][v], (*gridp)[h-1][v], (*gridp)[h][v]);
trycapture((*gridp)[h][v-2], (*gridp)[h][v-1], (*gridp)[h][v]);
trycapture((*gridp)[h+2][v], (*gridp)[h+1][v], (*gridp)[h][v]);
trycapture((*gridp)[h][v+2], (*gridp)[h][v+1], (*gridp)[h][v]);
if (onboard(&piece[THEKING])) {
/*
* The king is captured if there is a circle
* of muscovites (or the throne) surrounding the king
* and the circle was completed by the current move.
*/
kh = piece[THEKING].grid.h; kv = piece[THEKING].grid.v;
if (kingdanger(kh-1, kv) && kingdanger(kh, kv-1) &&
kingdanger(kh+1, kv) && kingdanger(kh, kv+1)) {
if ((*gridp)[kh-1][kv] == p || (*gridp)[kh][kv-1] == p ||
(*gridp)[kh+1][kv] == p || (*gridp)[kh][kv+1] == p) {
winner = BLACKWIN;
blinksquares(&(piece[THEKING].grid),
&(piece[THEKING].grid));
}
}
}
}
/*
* trycapture() - given three adjacent pieces (or nothing) see if the
* middle swede or muscovite (but not the swedish king) can be captured.
* If it can, remove it from the board.
*/
trycapture(pl, pc, pr)
struct pieceimage *pl, *pc, *pr; /* adjacent pieces to check */
{
if (!pl || !pc || !pr) return;
if (whitepiece(pl) && blackpiece(pc) && whitepiece(pr)) {
removepiece((int)(pc - &piece[0])); return;
}
if (blackpiece(pl) && classbase(pc) == FIRSTSWEDE && blackpiece(pr)) {
removepiece((int)(pc - &piece[0])); return;
}
}
/*
* kingdanger() - given grid coords of a position, see if there is direct
* danger to the king from that square -- I.E., see if that square is the
* throne or if it contains a black piece.
*/
int
kingdanger(h, v)
short h,v; /* coords to check */
{
if (h == 0 && v == 0) return(1);
if ((*gridp)[h][v] && blackpiece((*gridp)[h][v])) return(1);
return(0);
}
/*
* seeraichi() - see if there is a Raichi or Tuichi
*/
seeraichi()
{
Point minloc, maxloc; /* bounds of the king's movement */
Point raichis[4]; /* storage for raichi moves */
Point *rp; /* points to the next free raichi slot */
Point kingloc; /* the king's current grid coordinates */
int numraichis; /* number of raichis */
int blockable; /* "all raichis can be blocked" */
blockable = 1;
if (!onboard(&piece[THEKING])) return;
findbounds(THEKING, &minloc, &maxloc);
kingloc.h = piece[THEKING].grid.h; kingloc.v = piece[THEKING].grid.v;
rp = &raichis[0];
if (minloc.h == -4) {
SetPt(rp++, -4, kingloc.v);
blockable &= vblock(kingloc.v, -4, kingloc.h - 1);
}
if (minloc.v == -4) {
SetPt(rp++, kingloc.h, -4);
blockable &= hblock(kingloc.h, -4, kingloc.v - 1);
}
if (maxloc.h == 4) {
SetPt(rp++, 4, kingloc.v);
blockable &= vblock(kingloc.v, kingloc.h + 1, 4);
}
if (maxloc.v == 4) {
SetPt(rp++, kingloc.h, 4);
blockable &= hblock(kingloc.h, kingloc.v + 1, 4);
}
numraichis = (int)(rp - &raichis[0]);
if (numraichis >= 1) blinksquares(&raichis[0], rp - 1);
if (numraichis >= 2 || !blockable || (blacksmove() && numraichis >= 1)) {
winner = WHITEWIN;
}
}
/*
* vblock(), hblock() - see if the given row (or column) can be blocked by
* a black piece. This routine is used to see if a Raichi is blockable.
*/
int
vblock(kv, fromh, toh)
short kv; /* the row to be examined (the king's row) */
short fromh, toh; /* the bounds of the part to be blocked */
{
short h,v; /* grid square being examined for a piece */
for (h = fromh; h <= toh; ++h) {
for (v = kv - 1; v >= -4; --v) {
if ((*gridp)[h][v]) {
if (blackpiece((*gridp)[h][v])) return(1);
else break;
}
}
for (v = kv + 1; v <= 4; ++v) {
if ((*gridp)[h][v]) {
if (blackpiece((*gridp)[h][v])) return(1);
else break;
}
}
}
return(0);
}
int
hblock(kh, fromv, tov)
short kh; /* the col to be examined (the king's col) */
short fromv, tov; /* the bounds of the part to be blocked */
{
short h,v; /* grid square being examined for a piece */
for (v = fromv; v <= tov; ++v) {
for (h = kh - 1; h >= -4; --h) {
if ((*gridp)[h][v]) {
if (blackpiece((*gridp)[h][v])) return(1);
else break;
}
}
for (h = kh + 1; h <= 4; ++h) {
if ((*gridp)[h][v]) {
if (blackpiece((*gridp)[h][v])) return(1);
else break;
}
}
}
return(0);
}